package com.niiwoo.civet.trade.service.local.loan;

import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.trade.dao.entity.ProjectLoanDeadlineConfig;
import com.niiwoo.civet.trade.dao.entity.ProjectLoanDeadlineDisplayConfig;
import com.niiwoo.civet.trade.dao.entity.ProjectRateConfig;
import com.niiwoo.civet.trade.dao.mapper.ProjectLoanDeadlineConfigMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectLoanDeadlineDisplayConfigMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectRateConfigMapperExt;
import com.niiwoo.civet.trade.dto.common.SpeedLoanRateConfigDTO;
import com.niiwoo.civet.trade.dto.response.SpeedLoanConfigurationResponseDTO;
import com.niiwoo.civet.trade.enums.ProjectTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
 * @Author: wuke
 * @Description: 极速借借款配置业务处理类
 * @Date: Created in 16:26 2017/12/8
 */
@Slf4j
@Service
public class SpeedLoanRateConfigService {
    @Autowired
    private ProjectRateConfigMapperExt projectRateConfigMapper;
    @Autowired
    private ProjectLoanDeadlineConfigMapperExt projectLoanDeadlineConfigMapper;
    @Autowired
    private ProjectLoanDeadlineDisplayConfigMapperExt projectLoanDeadlineDisplayConfigMapper;

    /**
     * 获取所有费率配置信息--后期待加入缓存
     * @return
     */
    public List<ProjectRateConfig> getAllRateConfig(){
        return projectRateConfigMapper.selectAll();
    }

    /**
     * 获取所有费率配置信息--后期待加入缓存
     * @return
     */
    public List<ProjectRateConfig> getcardNiuAllRateConfig(Byte configType){
        return projectRateConfigMapper.selectAllByType(configType);
    }

    /**
     * 获取所有借款期限配置信息--后期待加入缓存
     * @return
     */
    public List<ProjectLoanDeadlineConfig> getAllLoanDeadlineConfig(){
        return projectLoanDeadlineConfigMapper.selectAll(ProjectTypeEnum.PERSONAL_SPEEDLOAN);
    }

    /**
     * 获取所有借款期限配置信息--后期待加入缓存
     * @return
     */
    public List<ProjectLoanDeadlineDisplayConfig> getAllLoanDeadlineDisplayConfig(){
        return projectLoanDeadlineDisplayConfigMapper.selectAll();
    }

    /**
     * 根据借款期限获取费率配置信息
     * @param deadline
     * @return
     */
    public ProjectRateConfig getRateConfigByDeadline(Integer deadline){
        List<ProjectRateConfig> rateConfigList = this.getAllRateConfig();
        if(CollectionUtils.isEmpty(rateConfigList)){
            return null;
        }
        for(ProjectRateConfig config:rateConfigList){
            if(config.getDeadline().intValue()==deadline.intValue()){
                return config;
            }
        }
        return null;
    }


    /**
     * 卡牛根据借款期限获取费率配置信息
     * @param deadline
     * @return
     */
    public ProjectRateConfig getCardcardniuRateConfigByDeadline(Integer deadline){
        List<ProjectRateConfig> rateConfigList = this.getcardNiuAllRateConfig(ProjectTypeEnum.CARD_NIU_LOAN.getValue());
        if(CollectionUtils.isEmpty(rateConfigList)){
            return null;
        }
        for(ProjectRateConfig config:rateConfigList){
            if(config.getDeadline().intValue()==deadline.intValue()){
                return config;
            }
        }
        return null;
    }

    /**
     * 根据金额获取费率配置信息
     * @param amount
     * @return
     */
    public List<ProjectRateConfig> getRateConfigDisplayByAviAmount(BigDecimal amount){
        List<Integer> loanDeadlineList = this.getLoanDeadlineDisplayListByAmount(amount);
        if(CollectionUtils.isEmpty(loanDeadlineList)){
            return null;
        }
        List<ProjectRateConfig> allRateConfigList = this.getAllRateConfig();
        if(CollectionUtils.isEmpty(allRateConfigList)){
            return null;
        }
        List<ProjectRateConfig> rateConfigList = new ArrayList<>();
        for(ProjectRateConfig rateConfig:allRateConfigList){
            if(loanDeadlineList.contains(rateConfig.getDeadline())){
                rateConfigList.add(rateConfig);
            }
        }
        return rateConfigList;
    }

    /**
     * 根据金额获取费率配置信息
     * @param loanAmount
     * @return
     */
    public List<ProjectRateConfig> getRateConfigByLoanAmount(BigDecimal loanAmount){
        List<Integer> loanDeadlineList = this.getLoanDeadlineListByLoanAmount(loanAmount);
        if(CollectionUtils.isEmpty(loanDeadlineList)){
            return null;
        }
        List<ProjectRateConfig> allRateConfigList = this.getAllRateConfig();
        if(CollectionUtils.isEmpty(allRateConfigList)){
            return null;
        }
        List<ProjectRateConfig> rateConfigList = new ArrayList<>();
        for(ProjectRateConfig rateConfig:allRateConfigList){
            if(loanDeadlineList.contains(rateConfig.getDeadline())){
                rateConfigList.add(rateConfig);
            }
        }
        return rateConfigList;
    }

    /**
     * 根据金额获取借款期限配置信息
     * @param amount
     * @return
     */
    public List<ProjectLoanDeadlineConfig> getLoanDeadlineConfigByAmount(BigDecimal amount){
        List<ProjectLoanDeadlineConfig> loanDeadlineConfigList = this.getAllLoanDeadlineConfig();
        if(CollectionUtils.isEmpty(loanDeadlineConfigList)){
            return null;
        }
        List<ProjectLoanDeadlineConfig> resultList = new ArrayList<>();
        for(ProjectLoanDeadlineConfig config : loanDeadlineConfigList){
            if(!(amount.compareTo(config.getMinLoanAmount())<0)){
                resultList.add(config);
            }
        }
        return resultList;
    }

    public ProjectLoanDeadlineDisplayConfig getLoanDeadlineDisplayConfigByAviAmount(BigDecimal aviAmount){
        List<ProjectLoanDeadlineDisplayConfig> loanDeadlineDisplayConfigList = this.getAllLoanDeadlineDisplayConfig();
        if(CollectionUtils.isEmpty(loanDeadlineDisplayConfigList)){
            return null;
        }
        for(ProjectLoanDeadlineDisplayConfig config : loanDeadlineDisplayConfigList){
            if(aviAmount.compareTo(config.getMinLoanAmount())>=0 && aviAmount.compareTo(config.getMaxLoanAmount())<=0){
                return config;
            }
        }
        return null;
    }

    /**
     * 根据金额，获取所有可选借款期限（已排序）
     * @param amount
     * @return
     */
    public List<Integer> getLoanDeadlineDisplayListByAmount(BigDecimal amount){
        ProjectLoanDeadlineDisplayConfig projectLoanDeadlineDisplayConfig = this.getLoanDeadlineDisplayConfigByAviAmount(amount);
        if(projectLoanDeadlineDisplayConfig==null){
            return null;
        }
        String deadline = projectLoanDeadlineDisplayConfig.getDeadline();
        if(!StringUtils.hasText(deadline)){
            return null;
        }
        String[] deadlineArray = deadline.split(",");

        Set<Integer> loanDeadlineSet = new TreeSet<Integer>();
        for(String deadlineStr : deadlineArray){
            loanDeadlineSet.add(Integer.valueOf(deadlineStr));
        }
        return new ArrayList<>(loanDeadlineSet);
    }

    public ProjectLoanDeadlineConfig getLoanDeadlineConfigByLoanAmount(BigDecimal loanAmount){
        List<ProjectLoanDeadlineConfig> loanDeadlineList = this.getAllLoanDeadlineConfig();
        if(CollectionUtils.isEmpty(loanDeadlineList)){
            return null;
        }
        for(ProjectLoanDeadlineConfig config : loanDeadlineList){
            if(loanAmount.compareTo(config.getMinLoanAmount())>=0 && loanAmount.compareTo(config.getMaxLoanAmount())<=0){
                return config;
            }
        }
        return null;
    }

    /**
     * 根据金额，获取所有可选借款期限（已排序）
     * @param loanAmount
     * @return
     */
    public List<Integer> getLoanDeadlineListByLoanAmount(BigDecimal loanAmount){
        ProjectLoanDeadlineConfig loanDeadlineConfig = this.getLoanDeadlineConfigByLoanAmount(loanAmount);
        if(loanDeadlineConfig==null){
            return null;
        }
        String deadline = loanDeadlineConfig.getDeadline();
        if(!StringUtils.hasText(deadline)){
            return null;
        }
        String[] deadlineArray = deadline.split(",");

        Set<Integer> loanDeadlineSet = new TreeSet<Integer>();
        for(String deadlineStr : deadlineArray){
            loanDeadlineSet.add(Integer.valueOf(deadlineStr));
        }
        return new ArrayList<>(loanDeadlineSet);
    }

    public SpeedLoanConfigurationResponseDTO getSpeedLoanRateConfig(BigDecimal speedLoanAviAmount){
        //获取所有期限对应的利率配置--在可用额度允许范围之内
        SpeedLoanConfigurationResponseDTO responseDTO = new SpeedLoanConfigurationResponseDTO();
        log.info("SpeedLoanRateConfigService.getSpeedLoanRateConfig.speedLoanCreditTotalAmount={} start",speedLoanAviAmount);
        List<ProjectRateConfig> rateConfigList = this.getRateConfigDisplayByAviAmount(speedLoanAviAmount);
        log.info("SpeedLoanRateConfigService.getSpeedLoanRateConfig.speedLoanCreditTotalAmount={},rateConfigList={}",speedLoanAviAmount,JSON.toJSONString(rateConfigList));
        if(CollectionUtils.isEmpty(rateConfigList)){
            log.info("SpeedLoanRateConfigService.getSpeedLoanRateConfig.speedLoanCreditTotalAmount={} 未能获取借款配置数据",speedLoanAviAmount);
            return responseDTO;
        }

        List<SpeedLoanRateConfigDTO> paramsRateList = new ArrayList<>();
        BigDecimal bigDecimal_100 = new BigDecimal("100");
        for(ProjectRateConfig rateConfig : rateConfigList){
            SpeedLoanRateConfigDTO rateConfigDTO = new SpeedLoanRateConfigDTO();
            rateConfigDTO.setRepaymentType(rateConfig.getRepaymentMode());
            rateConfigDTO.setBorrowMonth(rateConfig.getDeadline());
            rateConfigDTO.setLoanRate(this.bigDecimalNullToZeroFormat(rateConfig.getBorrowInterestRate()).multiply(bigDecimal_100));
            rateConfigDTO.setPlatformManageFeeRate(this.bigDecimalNullToZeroFormat(rateConfig.getPlatformManageFeeRate()).multiply(bigDecimal_100));
            rateConfigDTO.setCommissionGuaranteRate(this.bigDecimalNullToZeroFormat(rateConfig.getGuaranteeServiceFeeRate()).multiply(bigDecimal_100));
            paramsRateList.add(rateConfigDTO);
        }
        responseDTO.setParamsRateList(paramsRateList);

        //设置可选借款期限--在授信额度允许范围之内
        responseDTO.setDeadlineList(this.getLoanDeadlineDisplayListByAmount(speedLoanAviAmount));


        //借款期限配置列表
        List<ProjectLoanDeadlineConfig> loanDeadlineConfigList = this.getLoanDeadlineConfigByAmount(speedLoanAviAmount);
        log.info("SpeedLoanRateConfigService.getSpeedLoanRateConfig.speedLoanCreditTotalAmount={},loanDeadlineConfigList={}",speedLoanAviAmount,JSON.toJSONString(loanDeadlineConfigList));
        List<SpeedLoanConfigurationResponseDTO.DeadLineConfig> deadlineConfigList = new ArrayList<>();
        for(ProjectLoanDeadlineConfig loanDeadlineConfig : loanDeadlineConfigList){
            SpeedLoanConfigurationResponseDTO.DeadLineConfig deadlineConfigDTO = new SpeedLoanConfigurationResponseDTO.DeadLineConfig();
            deadlineConfigDTO.setMinAmount(loanDeadlineConfig.getMinLoanAmount());
            deadlineConfigDTO.setMaxAmount(loanDeadlineConfig.getMaxLoanAmount());
            deadlineConfigDTO.setDeadLineList(this.getDealLineList(loanDeadlineConfig.getDeadline()));
            deadlineConfigList.add(deadlineConfigDTO);
        }
        responseDTO.setDeadlineConfigList(deadlineConfigList);
        log.info("SpeedLoanRateConfigService.getSpeedLoanRateConfig.speedLoanCreditTotalAmount={},responseDTO={}",speedLoanAviAmount,JSON.toJSONString(responseDTO));

        return responseDTO;
    }

    private BigDecimal bigDecimalNullToZeroFormat(BigDecimal data) {
        return data == null ? new BigDecimal(0) : data;
    }

    private List<Integer> getDealLineList(String deadLine){
        if (!StringUtils.hasText(deadLine)) {
            return null;
        }
        String[] dealLineArray = deadLine.split(",");
        if(dealLineArray==null || dealLineArray.length==0){
            return null;
        }
        List<Integer> deadLineList = new ArrayList<>();
        for(int i=0;i<dealLineArray.length;i++){
            String dealLine = dealLineArray[i];
            deadLineList.add(Integer.valueOf(dealLine));
        }
        return deadLineList;
    }
}
